/**
 * Urban Parks
 *
 * Team M&M's:
 * Michael Satran Jr
 * Michael Pogson
 * Stephen Hunter
 *
 * Date: Feb 21, 2012
 */
package tests;

import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import model.Date;
import model.Job;
import model.Park;
import model.ParkManager;
import model.StaffMember;
import model.User;
import model.Volunteer;

import org.junit.Before;
import org.junit.Test;

import controller.Controller;

/**
 * @author Michael Pogson
 *
 */
public class ControllerTest {
		
	Controller cntrl;
	

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		
		Map<String, User> user_map = new HashMap<String, User>();
		createUserMap(user_map);
	    Collection<Volunteer> volunteer_list = new ArrayList<Volunteer>();
	    createVolunteerList(volunteer_list);
		Collection<Park> park_list = new ArrayList<Park>();
		createParkList(park_list);
		
		 cntrl = new Controller(user_map, volunteer_list, park_list);
		
		
	}
	
	/**
	 * Creates the users for the tests
	 */
	private void createUserMap(Map<String,User> the_map) {
		
		Volunteer vol = new Volunteer("mike", "pogson", "253", "abc@abc.com",false);
		Volunteer vol1 = new Volunteer("tyler", "root", "253", "123@abc.com",false);
		ParkManager pm = new ParkManager("harry", "potter", "253", "sss@abc.com");
		StaffMember sm = new StaffMember("yogi", "bear", "253", "ttt@abc.com");
		
		the_map.put(vol.getEmail(), vol);
		the_map.put(vol1.getEmail(), vol1);
		the_map.put(pm.getEmail(), pm);
		the_map.put(sm.getEmail(), sm);
		
		
	}
	
	/**
	 * Creates a volunteers lists
	 */
	private void createVolunteerList(Collection<Volunteer> the_list) {
		Volunteer vol = new Volunteer("mike", "pogson", "253", "abc@abc.com",false);
		Volunteer vol1 = new Volunteer("tyler", "root", "253", "123@abc.com",false);
		
		
		the_list.add(vol);
		the_list.add(vol1);
	}
	
	/**
	 * Creates a list of parks
	 * 
	 */
	private void createParkList(Collection<Park> park_list) {
		
		Date date = new Date(3,13,2012);
		Date date1 = new Date(3,14,2012);
		Date date2 = new Date(3,15,2012);
		Date compdate = new Date(3,14,2012);
		Date compdate1 = new Date(3,15,2012);
		Date compdate2 = new Date(3,16,2012);
		Date date3 = new Date(3,16,2012);
		Date date4 = new Date(3,17,2012);
		Date date5 = new Date(3,18,2012);
		Date compdate3 = new Date(3,17,2012);
		Date compdate4 = new Date(3,18,2012);
		Date compdate5 = new Date(3,19,2012);
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date date9 = new Date(3,22,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
		Date compdate9 = new Date(3,23,2012);
		
		ArrayList<Job> jobs = new ArrayList<Job>();
		
		Job job1 = new Job(date, compdate, "load of fun", 1);
		Job job2 = new Job(date1, compdate1, "okay", 2);
		Job job3 = new Job(date2, compdate2, "busy", 3);
		
		jobs.add(job1);
		jobs.add(job2);
		jobs.add(job3);
		
		Job job4 = new Job(date3, compdate3, "lame", 1);
		Job job5 = new Job(date4, compdate4, "TEST", 2);
		Job job6 = new Job(date5, compdate5, "hard", 3);
		
		ArrayList<Job> jobs2 = new ArrayList<Job>();
		
		jobs2.add(job4);
		jobs2.add(job5);
		jobs2.add(job6);
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		
		ArrayList<Job> jobs3 = new ArrayList<Job>();
		
		jobs3.add(job7);
		jobs3.add(job8);
		jobs3.add(job9);
		
		Park park1 = new Park(jobs, "fun time park", "urban", "rainer");
		Park park2 = new Park(jobs3, "lame park", "urban", "fun");
		Park park3 = new Park(jobs2, "crappy park", "west", "cool");
		
		park_list.add(park1);
		park_list.add(park2);
		park_list.add(park3);
	}
	
	/**
	 * Creates a list of jobs
	 * @param job_list the list to be added to
	 */
	private void createJobList(Collection<Job> job_list) {
		
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
	
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		

		job_list.add(job7);
		job_list.add(job8);
		job_list.add(job9);
	}


	/**
	 * Test method for adding a job.
	 */
	@Test
	public void testAddJob() {
		
		
		Collection<Job> jobs = new ArrayList<Job>();
		
		Date date = new Date(4,13,2012);
		Date compdate = new Date(4,14,2012);
		
		String jobDescription = "fun for kids!";
		int jobDifficulty = 3;
		String parkName = "lame park";
		
		createJobList(jobs);
		
		Job job = new Job(compdate, date, jobDescription, jobDifficulty);
		
		jobs.add(job);
		
		cntrl.addJob(job, parkName);
		
		ArrayList<Park> parks = new ArrayList<Park>(cntrl.getParks());
		
		ArrayList<Job> the_jobs = new ArrayList<Job>(jobs);
		
		ArrayList<Job> the_jobs2 = new ArrayList<Job>(parks.get(1).getJobs());
		
		 assertTrue(the_jobs.containsAll(the_jobs2) && the_jobs2.containsAll(the_jobs) &&
				 the_jobs.size() == the_jobs2.size());
	}

	/**
	 * Test method for adding a volunteer to a job.
	 */
	@Test
	public void testAddVolunteerToJob() {
		
		ArrayList<Park> parks = new ArrayList<Park>(cntrl.getParks());
		ArrayList<Job> jobs = new ArrayList<Job>(parks.get(1).getJobs());
		ArrayList<Volunteer> vol = new ArrayList<Volunteer>(cntrl.getAllVolunteers());
		ArrayList<Volunteer> volforjob = new ArrayList<Volunteer>(jobs.get(1).getVolunteers());
		
		
		volforjob.add(vol.get(1));
		cntrl.setCurrentUser(vol.get(1).getEmail());
		
		cntrl.addVolunteerToJob("lame park", jobs.get(1));
		
		
		ArrayList<Volunteer> volforjob2 = new ArrayList<Volunteer>(jobs.get(1).getVolunteers());

		assertEquals("didnt equal",volforjob ,volforjob2);
	}

	/**
	 * Test method for black balling a volunteer.
	 */
	@Test
	public void testBlackBallVolunteer() {
		ArrayList<Volunteer> vol = new ArrayList<Volunteer>(cntrl.getAllVolunteers());
		
		vol.get(1).blackBall();
		
		assertEquals("Not black Balled!", true, vol.get(1).isBlackBalled());
	}
	
	/**
	 * Test to see if add job will fail with bad date set to far into the future.
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testBadDateForAddJob(){ 
		
		Date date = new Date(4,13,2013);
		Date compdate = new Date(4,14,2013);
		
		String jobDescription = "fun for kids!";
		int jobDifficulty = 3;
		String parkName = "lame park";
		
		Job job = new Job(compdate, date, jobDescription, jobDifficulty);
		
		
		cntrl.addJob(job, parkName);
	}
	
	/**
	 * Tests to see if an exception is thrown when the Job is null
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testNullJob() {
		
		String parkName = "lame park";
		Job job = null;
		
		cntrl.addJob(job, parkName);
		
	}

	/**
	 * Tests to see if an exception is thrown when the Job total is at 30.
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testToManyJobs() {
		

		Date date = new Date(4,13,2013);
		Date compdate = new Date(4,14,2013);
		
		String jobDescription = "fun for kids!";
		int jobDifficulty = 3;
		String parkName = "lame park";
		
		Job job = new Job(compdate, date, jobDescription, jobDifficulty);
		
		cntrl.setTotalJobs(30);
		
		cntrl.addJob(job, parkName);
	}
	
	/**
	 * Tests to see if an exception is thrown when the jobs in a week is at 5.
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testToManyJobsInWeek() {
		
		Date date = new Date(4,8,2012);
		Date compdate = new Date(4,9,2012);
		
		String jobDescription = "fun for kids!";
		int jobDifficulty = 3;
		String parkName = "lame park";
		
		Job job = new Job(compdate, date, jobDescription, jobDifficulty);
		
		Date date2 = new Date(4,9,2012);
		Date compdate2 = new Date(4,10,2012);
		
		Job job2 = new Job(compdate2, date2, jobDescription, jobDifficulty);
		
		Date date3 = new Date(4,9,2012);
		Date compdate3 = new Date(4,11,2012);
		
		Job job3 = new Job(compdate3, date3, jobDescription, jobDifficulty);
		
		Date date4 = new Date(4,10,2012);
		Date compdate4 = new Date(4,11,2012);
		
		Job job4 = new Job(compdate4, date4, jobDescription, jobDifficulty);

		
		Date date5 = new Date(4,11,2012);
		Date compdate5 = new Date(4,12,2012);
		
		Job job5 = new Job(compdate5, date5, jobDescription, jobDifficulty);
		
		Date date6 = new Date(4,11,2012);
		Date compdate6 = new Date(4,12,2012);
		
		Job job6 = new Job(compdate6, date6, jobDescription, jobDifficulty);

		
		cntrl.addJob(job, parkName);
		cntrl.addJob(job2, parkName);
		cntrl.addJob(job3, parkName);
		cntrl.addJob(job4, parkName);
		cntrl.addJob(job5, parkName);
		cntrl.addJob(job6, parkName);
		
	}
	
	/**
	 * Test for a null volunteer
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testNullVolunteer() {
		Volunteer vol = null;
		Date date = new Date(4,13,2012);
		Date compdate = new Date(4,14,2012);
		
		String jobDescription = "fun for kids!";
		int jobDifficulty = 3;
		String parkName = "lame park";
		
		Job job = new Job(compdate, date, jobDescription, jobDifficulty);
		
		cntrl.addVolunteerToJob(parkName, job);
	}
	
	/**
	 * Test for a black ball volunteer cannot sign up
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testBlackBallVolunteerJob() {
		
		Volunteer voltest = new Volunteer("mike", "pogson", "253", "abc@abc.com",true);
			Date date = new Date(4,13,2012);
			Date compdate = new Date(4,14,2012);
			
			String jobDescription = "fun for kids!";
			int jobDifficulty = 3;
			String parkName = "lame park";
			
			Job job = new Job(compdate, date, jobDescription, jobDifficulty);
			
			cntrl.setCurrentUser(voltest.getEmail());
			((Volunteer)cntrl.getCurrentUser()).blackBall();
			cntrl.addVolunteerToJob(parkName, job);
		
	}
	

	/**
	 * Test for a black ball volunteer cannot sign up
	 */
	@Test(expected=IllegalArgumentException.class)
	public void testVolunteerAllreadyOnJob() {
		
		Volunteer vol = new Volunteer("mike", "pogson", "253", "abc@abc.com",false);
			Date date = new Date(4,13,2012);
			Date compdate = new Date(4,14,2012);
			
			String jobDescription = "fun for kids!";
			int jobDifficulty = 3;
			String parkName = "lame park";
			
			Job job = new Job(compdate, date, jobDescription, jobDifficulty);
			
			cntrl.setCurrentUser(vol.getEmail());
			cntrl.addVolunteerToJob(parkName, job);
			cntrl.addVolunteerToJob(parkName, job);
		
	}
	
	/**
	 * Tests to make sure we get all jobs that are in that district and jobs that arent are removed.
	 */
	@Test
	public void testGetJobsByDistrict() {
		ArrayList<Job> expected = new ArrayList<Job>();
		
		Date date = new Date(3,13,2012);
		Date date1 = new Date(3,14,2012);
		Date date2 = new Date(3,15,2012);
		Date compdate = new Date(3,14,2012);
		Date compdate1 = new Date(3,15,2012);
		Date compdate2 = new Date(3,16,2012);
		Date date3 = new Date(3,16,2012);
		Date date4 = new Date(3,17,2012);
		Date date5 = new Date(3,18,2012);
		Date compdate3 = new Date(3,17,2012);
		Date compdate4 = new Date(3,18,2012);
		Date compdate5 = new Date(3,19,2012);
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
		
		
		Job job1 = new Job(date, compdate, "load of fun", 1);
		Job job2 = new Job(date1, compdate1, "okay", 2);
		Job job3 = new Job(date2, compdate2, "busy", 3);
		
		Job job4 = new Job(date3, compdate3, "lame", 1);
		Job job5 = new Job(date4, compdate4, "TEST", 2);
		Job job6 = new Job(date5, compdate5, "hard", 3);
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		
		expected.add(job1);
		expected.add(job7);
		expected.add(job2);
		expected.add(job8);
		expected.add(job3);
		expected.add(job9);
		
		ArrayList<Job> alljobs = new ArrayList<Job>();
		
		alljobs.add(job1);
		alljobs.add(job7);
		alljobs.add(job2);
		alljobs.add(job8);
		alljobs.add(job3);
		alljobs.add(job9);
		alljobs.add(job4);
		alljobs.add(job5);
		alljobs.add(job6);
		
		
		ArrayList<Job> returnedList = new ArrayList<Job>(cntrl.getOpenJobsByDistrict("urban", alljobs));
		
		System.out.println("sizes: " + returnedList.size() + " and " + expected.size());
		
		assertTrue(returnedList.containsAll(expected) && expected.containsAll(returnedList) &&
					returnedList.size() == expected.size());
		
	}
	
	public void testGetJobsByRegion() {
		
	ArrayList<Job> expected = new ArrayList<Job>();
		
		Date date = new Date(3,13,2012);
		Date date1 = new Date(3,14,2012);
		Date date2 = new Date(3,15,2012);
		Date compdate = new Date(3,14,2012);
		Date compdate1 = new Date(3,15,2012);
		Date compdate2 = new Date(3,16,2012);
		Date date3 = new Date(3,16,2012);
		Date date4 = new Date(3,17,2012);
		Date date5 = new Date(3,18,2012);
		Date compdate3 = new Date(3,17,2012);
		Date compdate4 = new Date(3,18,2012);
		Date compdate5 = new Date(3,19,2012);
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
		
		
		Job job1 = new Job(date, compdate, "load of fun", 1);
		Job job2 = new Job(date1, compdate1, "okay", 2);
		Job job3 = new Job(date2, compdate2, "busy", 3);
		
		Job job4 = new Job(date3, compdate3, "lame", 1);
		Job job5 = new Job(date4, compdate4, "TEST", 2);
		Job job6 = new Job(date5, compdate5, "hard", 3);
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		
		expected.add(job6);
		expected.add(job5);
		expected.add(job4);

		
		ArrayList<Job> alljobs = new ArrayList<Job>();
		
		alljobs.add(job1);
		alljobs.add(job7);
		alljobs.add(job2);
		alljobs.add(job8);
		alljobs.add(job3);
		alljobs.add(job9);
		alljobs.add(job4);
		alljobs.add(job5);
		alljobs.add(job6);
		
		
		ArrayList<Job> returnedList = new ArrayList<Job>(cntrl.getOpenJobsByRegion("cool", alljobs));
		
		System.out.println("sizes: " + returnedList.size() + " and " + expected.size());
		
		assertTrue(returnedList.containsAll(expected) && expected.containsAll(returnedList) &&
					returnedList.size() == expected.size());
	}
	
	
	/**
	 * This method tests to see if we get the right jobs by park name.
	 */
	@Test
	public void testGetJobsByParkName() {
		
	ArrayList<Job> expected = new ArrayList<Job>();
		
		Date date = new Date(3,13,2012);
		Date date1 = new Date(3,14,2012);
		Date date2 = new Date(3,15,2012);
		Date compdate = new Date(3,14,2012);
		Date compdate1 = new Date(3,15,2012);
		Date compdate2 = new Date(3,16,2012);
		Date date3 = new Date(3,16,2012);
		Date date4 = new Date(3,17,2012);
		Date date5 = new Date(3,18,2012);
		Date compdate3 = new Date(3,17,2012);
		Date compdate4 = new Date(3,18,2012);
		Date compdate5 = new Date(3,19,2012);
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
		
		
		Job job1 = new Job(date, compdate, "load of fun", 1);
		Job job2 = new Job(date1, compdate1, "okay", 2);
		Job job3 = new Job(date2, compdate2, "busy", 3);
		
		Job job4 = new Job(date3, compdate3, "lame", 1);
		Job job5 = new Job(date4, compdate4, "TEST", 2);
		Job job6 = new Job(date5, compdate5, "hard", 3);
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		
		expected.add(job1);
		expected.add(job2);
		expected.add(job3);

		
		ArrayList<Job> alljobs = new ArrayList<Job>();
		
		alljobs.add(job1);
		alljobs.add(job7);
		alljobs.add(job2);
		alljobs.add(job8);
		alljobs.add(job3);
		alljobs.add(job9);
		alljobs.add(job4);
		alljobs.add(job5);
		alljobs.add(job6);
		
		
		ArrayList<Job> returnedList = new ArrayList<Job>(cntrl.getOpenJobsByPark("fun time park", alljobs));
		
		System.out.println("sizes: " + returnedList.size() + " and " + expected.size());
		
		assertTrue(returnedList.containsAll(expected) && expected.containsAll(returnedList) &&
					returnedList.size() == expected.size());
	}
	
	/**
	 * Tests to make sure that all district names are collected.
	 */
	@Test
	public void testGetDistrictNames() {
		
		ArrayList<String> expected = new ArrayList<String>();
		expected.add("urban");
		expected.add("west");
		
		ArrayList<String> actual = new ArrayList<String>(cntrl.getDistricts());

		assertTrue(expected.containsAll(actual) && actual.containsAll(expected) &&
					expected.size() == actual.size());
		
	}
	
	/**
	 * Test to make sure that all the region names are collected.
	 */
	@Test
	public void testsGetRegionNames() {
		
		ArrayList<String> expected = new ArrayList<String>();
		expected.add("rainer");
		expected.add("fun");
		expected.add("cool");
		
		ArrayList<String> actual = new ArrayList<String>(cntrl.getRegions());

		assertTrue(expected.containsAll(actual) && actual.containsAll(expected) &&
					expected.size() == actual.size());

		
	}
	
	/**
	 * Test to make sure that all park names are collected.
	 */
	@Test
	public void testsGetParkNames() {
		
		ArrayList<String> expected = new ArrayList<String>();
		expected.add("fun time park");
		expected.add("lame park");
		expected.add("crappy park");
		
		ArrayList<String> actual = new ArrayList<String>(cntrl.getParkNames());

		assertTrue(expected.containsAll(actual) && actual.containsAll(expected) &&
					expected.size() == actual.size());
	
	}
	
	/**
	 * Test to make sure all jobs are returned.
	 */
	@Test
	public void testGetAllJobs() {
		
		ArrayList<Job> expected = new ArrayList<Job>();
		
		Date date = new Date(3,13,2012);
		Date date1 = new Date(3,14,2012);
		Date date2 = new Date(3,15,2012);
		Date compdate = new Date(3,14,2012);
		Date compdate1 = new Date(3,15,2012);
		Date compdate2 = new Date(3,16,2012);
		Date date3 = new Date(3,16,2012);
		Date date4 = new Date(3,17,2012);
		Date date5 = new Date(3,18,2012);
		Date compdate3 = new Date(3,17,2012);
		Date compdate4 = new Date(3,18,2012);
		Date compdate5 = new Date(3,19,2012);
		Date date6 = new Date(3,19,2012);
		Date date7 = new Date(3,20,2012);
		Date date8 = new Date(3,21,2012);
		Date compdate6 = new Date(3,20,2012);
		Date compdate7 = new Date(3,21,2012);
		Date compdate8 = new Date(3,22,2012);
		
		Job job1 = new Job(date, compdate, "load of fun", 1);
		Job job2 = new Job(date1, compdate1, "okay", 2);
		Job job3 = new Job(date2, compdate2, "busy", 3);
		
		Job job4 = new Job(date3, compdate3, "lame", 1);
		Job job5 = new Job(date4, compdate4, "TEST", 2);
		Job job6 = new Job(date5, compdate5, "hard", 3);
		
		Job job7 = new Job(date6, compdate6, "soft", 1);
		Job job8 = new Job(date7, compdate7, "easy", 2);
		Job job9 = new Job(date8, compdate8, "cheap", 3);
		
		expected.add(job1);
		expected.add(job2);
		expected.add(job3);
		expected.add(job4);
		expected.add(job5);
		expected.add(job6);
		expected.add(job7);
		expected.add(job8);
		expected.add(job9);
		
		ArrayList<Job> actual = new ArrayList<Job>(cntrl.getAllJobs());
		
		assertTrue(expected.containsAll(actual) && actual.containsAll(expected) &&
				expected.size() == actual.size());
		
	}
	
	/**
	 * Test to see if the correct jobs are returned for a volunteer.
	 */
	@Test
	public void testVolunteerInJob() {
		
		Volunteer vol = new Volunteer("mike", "pogson", "253", "abc@abc.com",false);
		Volunteer vol1 = new Volunteer("tyler", "root", "253", "123@abc.com",false);
		
	}
	
	
}
